\documentclass[a4paper,12pt]{article}
\usepackage[MeX]{polski}
\usepackage{color}
\usepackage{alltt}
\usepackage[utf8x]{inputenc}
\usepackage{graphicx}
\usepackage{graphics}
\usepackage{epsf}
\usepackage{amsthm,amsmath,amsfonts,amssymb}
\usepackage{array} 
\usepackage{url}
\author{Marta Truszczyńska, Marcin Dembowski}
\title{Analiza skupień przy użyciu samoorganizującej się sieci Kohonena}

\newtheorem{tw}{Twierdzenie}[section]
\theoremstyle{definition}
\newtheorem{defi}[tw]{Definicja}

\frenchspacing
\begin{document}
\maketitle
\begin{abstract}
Niniejsza praca poświęcona jest zastosowaniu samoorganizującej się sieci Kohonena do analizy skupień.

Program oraz niniejsza dokumentacja dostępna jest do ściągnięcia na stronie
http://code.google.com/p/trudemall/
\end{abstract}
\clearpage
\tableofcontents

\newpage

\section{Streszczenie pracy}
Niniejsza praca opisuje sieci neuronowe Kohonena, za pomocą których dokonano analizy skupień. Sieci Kohonena służą do eksploracji bez nadzoru zbiorów informacji. Sieć ta jest sztuczną siecią neuronową, której budowa jest wzorowana na właściwościach mózgu ludzkiego. Podstawą tej sieci są dwie warstwy neuronów. Z każdym neuronem jest powiązany wektor wag o wymiarze takim samym jak wektor elementu wejściowego. Danymi jakie wykorzystano w tej pracy jest wielowymiarowy zbiór na temat irysów. Występują w nim trzy klasy irysów, a algorytm samoorganizującej się sieci ma na celu rozpoznać te klasy. Wynik działania algorytmu zaprezentowany jest w postaci graficznej. 
\newpage

\section{Wprowadzenie do tematyki analizy skupień za pomocą sieci Kohonena}
%Motywacja%
%Background%

%
% SIECI NEURONOWE
%
\subsection{Sieci neuronowe}
Przed wyjaśnianiem zasady działania sieci Kohonena, warto przybliżyć ogólne zasady działania sieci neuronowych. Od lat naukowcy próbują stworzyć sztuczny mózg. Obserwując mózg człowieka i zwierząt odkryto wiele cech i właściwości tego narządu. Zauważono, że poszczególne części mózgu odpowiedzialne są za konkretne funkcje, na przykład rozpoznawanie dźwięku, obrazu, smaku i zapachu mówienie, a także charakter człowieka i zachowanie. W dzisiejszych czasach mózg jest jedynym narządem, którego dokładną budowę i zasadę działania nie opisano. Wiadomo między innymi, że składa się z kilkunastu miliardów neuronów połączonych ze sobą i tworzących w ten sposób różnego rodzaju sieci. Najciekawszą właściwością jest fakt, że ludzie, którzy w wyniku wypadków utracili jedną półkulę, po określonym czasie mogą na nowo nauczyć się utraconych funkcji (druga półkula przejmuje funkcje pierwszej półkuli). 
\subsubsection{Zarys historyczny}
\par Na chwilę obecną, żaden model nie potrafi w pełni odzwierciedlić mózgu, jednak w pewien sposób potrafi przybliżyć zasadę działania. Różnego rodzaju rozważania na temat modelowania mózgu prowadzone były już od długiego czasu. Rozkwit wiedzy na temat tej dziedziny zaczął się po zakończeniu drugiej wojny światowej. Pierwszy model działającej sieci został zbudowany w roku 1957 przez Franka Rosenblatta i Charlesa Wightnaba. Perceptron - bo tak nazywała się ta sieć przeznaczona była do rozpoznawania znaków alfanumerycznych wraz z procesem uczenia. Model ten był bardzo wrażliwy na jakiekolwiek zmiany liter (obrót, oddalenie), jednak był sprawny nawet, jeżeli niektóre jego elementy nie działały. W Polsce doceniana była praca prof. Ryszarda Gawrońskiego powstała w latach 60-tych XX wieku. Do początku lat 90-tych XX wieku powstało wiele prac poświęconych zagadnieniu sieci neuronowych, jednak największe zapotrzebowanie na tą wiedzę zaczęło się w latach 90-tych. Do tego czasu dostęp i utworzenie różnego rodzaju sieci neuronowych było kosztowne, jednak wraz z rozwojem techniki dziedzina ta zaczęła się mocno rozwijać i stawała się dostępna dla wszystkich.
\par Przejdźmy do przedstawienia i omówienia niektórych modeli matematycznych sieci neuronowych przedstawiając podstawy teorii potrzebne przy analizie naszej sieci Kohonena.

\subsubsection{Neuron - podstawa sieci}
Podstawowym elementem mózgu (a także sieci neuronowych) jest neuron. Jest to komórka składająca się ciała komórki oraz wypustek. Wypustki te dzielą się na dendryty, czyli wypustki zbierające informację, akson - wyprowadzające informację. Różne komórki łączą się natomiast przy pomocy synaps. Wprowadzając przykład, wyobrazić możemy sobie farmę serwerów odzwierciedlających komórki oraz usługi typu WebService będące odpowiednikiem synaps. Serwery te komunikują się przy pomocy warstwy HTTP wymieniając się informacjami, a sama usługa sieci web (WebService) odpowiada za wymianę informacji pomiedzy różnymi serwerami.
\par Przedstawmy jednak model neuronu, który wyjaśni nam późniejszą budowę i zasadę działania sieci Kohonena. Zakładamy, że nasza komórka potrafi przyjąć $n$ różnych informacji. Informacje te trafiają do niej w postaci wektora
\begin{equation}
x=[x_1,\ldots,x_n]
\end{equation}
Każdy neuron posiada dodatkowo wektor wag, który określa w jakim stopniu trafiająca do niego informacja jest ważna. Dzięki temu neuron może specjalizować się w określonej dziedzinie.
\begin{equation}
w=[w_1,\ldots,w_n]
\end{equation}
Wartość wyjściowa (wychodząca z aksonu) wyliczana jest z poniższej zależności, zwanej funkcją aktywacji
\begin{equation}
y=f(s)
\end{equation}
gdzie
\begin{equation}
s=\sum_{i=1}^{n}x_i w_i
\end{equation}
Zauważyć można, że działanie neuronu opisane w powyższych wzorach jest bardzo łatwe. Wprowadzamy informację w postaci wektora $x$, neuron wylicza wartość używając do tego funkcji aktywacji $f$ i wag $w$. Natomiast cała wiedza kryje się w wagach $w_i$. Odpowiednio dobierając wagi możemy poszczególne neurony uczyć, a czasami nawet specjalizować określone fragmenty sieci do wykonywania określonych funkcjonalności. Przedstawiony model jest najprostszym modelem neuronu. 

\subsubsection{Sieć - spoiwem wiedzy}
W mózgu zwierząt nie występują pojedyncze komórki, które potrafiłyby rozstrzygnąć problem, czy zareagować na określony bodziec. Sama pojedyncza komórka może nie wiele dać nam informacji. Istnieją komórki, które pełnią funkcję czujników i regulatorów - na przykład komórki czuciowe reagujące na temperaturę. Przykładając rękę do grzejnika, komórka taka generuje sygnał, który wędruje do mózgu gdzie pobudza grupę komórek. Komórki te połączone z innymi komórkami mogą wysłać sygnał zwrotny nakazujący zgięcie ręki, w przypadku, gdy grzejnik jest za gorący.
\par Naukowcy badając mózg pod rezonansem magnetycznym zauważyli, że pod wpływem różnych bodźców, określone części mózgu stają się bardziej aktywne, a inne mniej. Podobnie można postąpić w przypadku naszej sztucznej sieci neuronowej, część sieci jest bardziej wrażliwa na określony gatunek irysa.
Istnieje wiele różnego rodzaju sieci neuronowych, które mają zastosowania w wielu różnych dziedzinach nauki. Głównie sieci dzielą się na sieci jedenokierunkowe, rekurencyjne i sieci samoorganizujące. Pojedyńcze neurony mogą być łączone ze sobą tworząc wielowarstwowe sieci. Przykładem zastosowania może być lokalizacja tablic rejestracyjnych pojazdów \cite{tablice}, wykorzystująca sieć trójwarstwową. Dodatkowo sieci neuronowe mogą zostać użyte do aproksymacji funkcji, klasteryzacji i analizy danych.
\par Przyjrzyjmy się jednak bliżej pewnej grupie sieci neuronowych, wykorzystanych w dołączonym programie.

\paragraph{Samoorganizujące sieci z konkurencją} Sieci tego rodzaju wykorzystujące uczenie bez nauczyciela lub uczeniem nienadzorowanym. Jak sama nazwa może nam podpowiadać, sieć uczy się na podstawie jedynie danych wejściowych bez wykorzystania i porównania wygenerowanego sygnału z wartością wzorcową. W naszym przypadku badając kwiaty irysa, sieć nasza będzie znała jedynie cztery wejściowe sygnały, bez informacji na temat gatunku. Sieci tego rodzaju są nieskomplikowane i mają szerokie zastosowanie w algorytmach grupowania danych. Sygnał wejściowy $x=[x_1,\ldots,x_n]$ trafia na wejścia wszystkich neuronów, gdzie wyznaczana jest miara podobieństwa. Sieci tego rodzaju dzielą się na dwa podstawowe typy.
\subparagraph{Sieć typu WTA} Winner Takes All - Jest to sieć, w której neuron, którego miara podobieństwa jest najmniejsza w stosunku do sygnału wejściowego, jako jedyny modyfikuje swoje wagi, przystosowując się do badanej wartości. Do badania odległości stosowana jest najczęściej miara euklidesowa
\begin{equation}
d(x,w_i)=||x-w_i||=\sqrt{\sum_{j=n}^{n}(x_j-w_{ij})^2}
\end{equation}
Działanie tego typu sieci sprowadza się do utworzenia $N$ różnych klas (tyle ile neuronów). Po nauczeniu sieci, każdy neuron reprezentuje środek klasy

\subparagraph{Sieć typu WTM} Winner Takes Most - sieć tego typu jest podobna do sieci WTA, z tą różnicą, że oprócz zwycięscy swoje wagi modyfikują także sąsiedzi zwycięskiego neuronu. Dobrym przykładem tego typu sieci jest algorytm Kohonena zaproponowana w roku 1982 w pracy \cite{kohonen_first}. Szczegóły implementacyjne omówione są w dalszych rozdziałach tej pracy. 

\par Omówiona powyżej zasada działania sztucznych sieci neuronowych jest tylko namiastką dostępnej na dzień dzisiejszy wiedzy z zakresu tej dziedziny. Istnieje wiele różnego rodzaju fachowej literatury, dzięki której czytelnik może samodzielnie zapoznać się ze szczegółami (\cite{rutkowski},\cite{tadeusiewicz}).
%metodologia%
%wyniki%
%reszta pracy%

\newpage
\section{Metodologia algorytmu samoorganizującej się sieci neuronowej}
\label{metod}
\subsection{Algorytm sieci Kohonena}
Stosowany w pracy algorytm sieci samoorganizującej się Kohonena, został zaproponowany przez niego pracy \cite{kohonen_first}. Algorytm Kohonena oraz inne algorytmy z dziedziny sieci neuronowych zostały opisane w pracy \cite{fri} autorstwa Fritzke. Prezentowany tutaj algorytm sieci samoorganizującej się sieci został napisany w oparciu o pracę Fritzke \cite{fri}.   
\par
System będący siecią Kohonena składa się z macierzy neuronów, która jest dwuwymiarową kratą (oznaczamy jako $a_{ij}$). Krata ta nie zmienia się w czasie samoorganizacji sieci. Ważną częścią algorytmu jest odległość na naszej macierzy neuronów. Odległość ta przekazuje nam informację o tym jak bardzo jednostka $r=a_{km}$ (czyli któryś z neuronów na kracie), jest zaadoptowana, kiedy jednostka $s=a_{ij}$ (czyli inny neuron na kracie) jest zwycięzcą (za zwycięzcę przyjmujemy najlepiej zaadaptowaną jednostkę). Stosowana miarą odległości jest $L_{1}-norma$ (nazywana też metryką Manhattan), którą możemy wyliczyć z wzoru:
\begin{equation}
\label{lnorm}
d_{1}(r,s)=|i-k|+|j-m|
\end{equation} 
gdzie $r=a_{km}$ oraz $s=a_{ij}$. W algorytmie duże znaczenie ma typ sąsiedztwa, za pomocą którego będziemy wyznaczać elementy do modyfikacji razem ze zwycięzcą $s$. Typ sąsiedztwa który zastosowaliśmy, to sąsiedztwo gaussowskie. Stopień adaptacji wag sąsiadów określamy w nim następującym wzorem:
\begin{equation}
\label{gauss}
h_{rs}=exp(\frac{-d_{1}(r,s)^{2}}{2\sigma ^{2}})
\end{equation}  
gdzie $r$ to pewna jednostka na kracie, $s$ to aktualny zwycięzca, $d_{1}(r,s)$ to miara odległości Manhattan, a $\sigma$ to odchylenie standardowe. Odchylenie standardowe wyliczamy z następującego wzoru:
\begin{equation}
\sigma (t)= \sigma _{i}(\frac{\sigma _{f}}{\sigma _{i}})^{\frac{t}{t_{max}}}
\end{equation}  
Wartości $\sigma _{i}$  oraz $\sigma _{f}$ są zmiennymi które należy odpowiednio dobrać. Opierając się na pracy Fritzke \cite{fri} ustawiliśmy je na $\sigma _{i} =3.0$  oraz $\sigma _{f} =0.1$.
\par
Początkiem algorytmu sieci samoorganizującej się Kohonena jest inicjalizacja warstwy neuronów, z której powstanie macierz neuronów. Tworzymy zbiór neuronów $A$ (o wielkości kraty, którą chcemy otrzymać) aby zawierał $N=N_{1}\cdot N_{2}$ jednostek $c_{1}$. Jeśli chcemy zrobić macierz $10\times 10$ neuronów, to tworzymy zbiór o wielkości $10\cdot 10=100$. Zbiór $A$ wygląda następująco:
\begin{equation}
A={c_{1},c_{2},...,c_{N}}
\end{equation}  
Każdy z neuronów musi posiadać powiązany z nim wektor wag $w_{c_{1}} \in R^{n}$. Wagi te inicjalizujemy losowo, biorąc pod uwagę wartości elementów wejściowych, których to odwzorowaniem są te wektory. Czyli przykładowo możemy brać losowe wartości z zakresu, który określają maksymalne i minimalne wartości elementów wejściowych. Użytymi przez nas elementami wejściowymi są dane opisujące kwiaty irysa. Poszczególny kwiat jest opisany czterema numerycznymi wartościami zmiennoprzecinkowymi: długość łodygi, szerokość łodygi, długość płatka, szerokość płatka. Dane te tworzą wektor czterech wartości wyglądający następująco:
\begin{equation}
I=[i_{1},i_{2},i_{3},i_{4}]
\end{equation} 
Warstwy neuronów oraz ich wektory wag zostały zaprezentowane na rysunku \ref{neurony}.

\begin{figure}[hbt]
\centering
\includegraphics[width=14cm]{obrazki/warstwyNeuronow.png}
\caption{Architektura warstwy neuronów algorytmu samoorganizującej się sieci Kohonena}
\label{neurony}
\end{figure}

Mając już neurony z wektorami wag, tworzymy opisaną kratę neuronów $N_{1}\times  N_{2}$, którą oznaczymy jako $C$. Ponadto inicjalizujemy parametr określający czas na $t=0$. Parametr czasu $t$ ma bezpośredni wpływ na promień sąsiedztwa. Zwiększanie wartości parametru $t$ (czyli upływ czasu od początku uczenia sie sieci) powoduje zmniejszanie się promienia sąsiedztwa. 
\par
Po inicjalizacji wszystkich potrzebnych wartości przechodzimy do pętli. Pętlę zaczynamy od wartości $t=0$ i wykonujemy obliczenia w niej dopóki $t < t_{max}$.
W pętli wykonujemy następujące kroki:
\begin{itemize} 
\item Bierzemy jeden z elementów wejściowych, który jest wektorem:
\begin{equation}
I=[i_{1},i_{2},i_{3},i_{4}]
\end{equation}  
\item Wyznaczamy zwycięzcę - neuron na kracie który jest najbliższy elementowi wejściowemu. Zwycięzcę $s(I)=s$ wyznaczamy z następującego wzoru:
\begin{equation}
s(I)=arg min_{c\in A} \| I - w_{c}\|
\end{equation}  
\item Następnym krokiem jest adaptacja jednostek. Wagi jednostki $s$ (zwycięskiego neuronu) oraz jego sąsiadów są zmieniane według wzoru:
\begin{equation}
\Delta w_{r} = \varepsilon (t) h_{rs} (I - w_{r})
\end{equation}  
gdzie $r$ jest pojedynczą jednostką - neuronem na kracie, $w_{r}$ to wektor wag tego elementu, $h_{rs}$ to sąsiedztwo gaussowskie zdefiniowane wzorem~\ref{gauss}, a $I$ to element wejściowy. $\varepsilon (t)$ obliczamy ze wzoru:
\begin{equation}
\varepsilon (t)=\varepsilon _{i}(\frac{\varepsilon _{f}}{\varepsilon _{i}})^{\frac{t}{t_{max}}}
\end{equation}  
\item Ostatnim krokiem w pętli jest zwiększenie licznika czasu $t$:
\begin{equation}
t = t + 1
\end{equation}      
\end{itemize} 
W zależności od tego na ile ustawimy wartość $t_{max}$, tyle razy wykona się powyższa pętla. 

\subsection{Implementacja algorytmu SOFM}
Głównym elementem programu jest klasa \textit{KohonenMap}, w której to zaimplementowany i wywoływany jest algorytm samoorganizującej się sieci Kohonena. W klasie tej są podane następujące stałe używane do obliczeń: 
\begin{equation}
 \sigma _{i} = 3.0 
\end{equation} 
\begin{equation}
\sigma _{f} = 0.1 
\end{equation} 
\begin{equation}
\varepsilon _{i} = 0.5
\end{equation} 
\begin{equation}
\varepsilon _{f} = 0.005 
\end{equation} 

Wartości tych stałych zostały wyznaczone w oparciu o artykuł Fritzke \cite{fri}. 
W konstruktorze klasy \textit{KohonenMap} ładowane są dane o irysach, z których później korzysta program. Główną metodą w tej klasie jest funkcja \textit{SOM}, która to jest implementacją algorytmu   
sieci Kohonena opisanego w podsekcji powyżej. Funkcja ta w pętli po zmiennej $t$, używając danych irysów jako danych wejściowych wykonuje kolejne kroki algorytmu. Funkcją pomocniczą tego algorytmu jest \textit{FindWinner}, która to wyszukuje zwycięzcę $s$, czyli neuron który jest najbliższy elementowi wejściowemu. Kolejnymi metodami pomocniczymi są funkcje \textit{AdaptationStrength}, która wylicza sąsiedztwo gaussowskie, funkcja \textit{ManhattanDistance} - oblicza metrykę Manhattan, funkcja \textit{Gaussian} - wylicza $\sigma (t)$ oraz funkcja \textit{Epsilon} - która oblicza $\varepsilon (t)$. 
\par
Ponadto w programie została zastosowana wielowątkowość aby przyspieszyć działanie programu. Niestety obliczenia algorytmu nie da się łatwo rozbić na poszczególne procesory, ponieważ nowe wyliczenia są zależne od poprzednich. Miejscem, w którym wykorzystaliśmy rozdzielenie obliczeń jest poszukiwanie zwycięzcy i modyfikacja wag sąsiadów. Program sam w sobie nie wykorzystuje wielowątkowości, a jedynie wiloprocesorowość - zależnie od liczby procesorów swoje obliczenia może rozkładać na poszczególne jednostki obliczeniowe. Wynikiem programu jest wizualizacja macierzy neuronów, która za pomocą różnych kolorów przedstawia znalezione skupienia.

\newpage
\section{Wyniki działania programu do analizy skupień}
\label{wyniki} 
\subsection{Program i jego wyniki}
Wyniki przedstawione w tej sekcji zostały uzyskane przy użyciu zaimplementowanego przez nas programu do analizy skupień za pomocą sieci samoorganizującej się Kohonena. Program ten jest oparty na metodologii opisanej w sekcji \ref{metod}. Dane jakie wykorzystaliśmy do analizy to 4-wymiarowy zbiór trzech gatunków irysów Fisher'a, który to jako pierwszy wykorzystał do badań w swojej pracy \cite{fisher}. Dane te można pobrać ze strony \url{http://archive.ics.uci.edu/ml/datasets/Iris}.

\begin{figure}[hbt]
\centering
\includegraphics[width=12cm]{obrazki/irys4_3000.png}
\caption{Program do analizy skupień za pomocą sieci samoorganizującej się Kohonena}
\label{program_irys}
\end{figure}

\begin{figure}[hbt]
\centering
\includegraphics[width=12cm]{obrazki/2_kol_czb_3000.png}
\caption{Krata z neuronami w trybie kolorów RGB oraz w skali szarości}
\label{szara_krata}
\end{figure}

\begin{figure}[hbt]
\centering
\includegraphics[width=14cm]{obrazki/3kolory_3000.png}
\caption{Porównanie trzech krat neuronów z poszczególnymi klasami irysów}
\label{krata_3kolory}
\end{figure}

\begin{figure}[hbt]
\centering
\includegraphics[width=14cm]{obrazki/2kolory_3000.png}
\caption{Porównanie dwóch krat neuronów: z trzema klasami i dwoma klasami irysów}
\label{krata_2kolory}
\end{figure}

\begin{figure}[hbt]
\centering
\includegraphics[width=14cm]{obrazki/3rozmiary_3000.png}
\caption{Porównanie trzech krat neuronów o wymiarach kolejno 3x3, 4x4 oraz 10x10}
\label{krata_rozmiary}
\end{figure}

\begin{figure}[hbt]
\centering
\includegraphics[width=12cm]{obrazki/3_iteracje.png}
\caption{Porównanie trzech krat neuronów powstałych z różnej ilości iteracji}
\label{krata_iteracje}
\end{figure}

\par
Przygotowana przez nas aplikacja korzysta ze zbioru danych o irysach i na podstawie algorytmu sieci samoorganizującej się Kohonena przedstawia graficzną reprezentację trzech klas irysów. Parametry jakie zmienić w panelu programu to: 
\begin{itemize} 
\item Ilość iteracji - możemy tutaj ustawić wartość z zakresu od 10 do 10000. Liczba ta jest wartością $t_{max}$, która bezpośrednio określa ile razy wykona się pętla w algorytmie oraz ma wpływ na sąsiedztwo gaussowskie neuronów. Dokładne wykorzystanie zmiennej $t_{max}$ zostało opisane w sekcji \ref{metod}. 
\item Krok rysowania - wpływa na wizualizację mapy klas w trakcie jej tworzenia. Określa co ile iteracji zmiany będą rysowane na wizualizacji graficznej. 
\item X oraz Y - oznaczają rozmiar kraty. Krata nie musi być kwadratowa, można również ustawić współrzędne X i Y tak aby krata miała kształt prostokąta.
\end{itemize}
Panel aplikacji z przykładowym wynikiem działania programu został przedstawiony na rysunku \ref{program_irys}. Wynik działania programu - wizualizację klas irysów możemy zobaczyć w trybie kolorów RGB lub w skali szarości. Porównanie tych dwóch trybów zostało zaprezentowane na rysunku \ref{szara_krata}. Zarówno na kracie ze skalą szarości jak i w trybie kolorowym można rozróżnić skupienia irysów. W trybie kolorowym, trzy różne kolory odpowiadają klasom irysów (zielony - Setosa, czerwony - Versicolor, niebieski - Virginica ). Aplikacja daje również możliwość obejrzenia poszczególnych skupień zarówno dla wszystkich trzech klas jak i dla dwóch klas oraz jednej klasy irysów. Zostało to zaprezentowane na rysunkach \ref{krata_2kolory} oraz \ref{krata_3kolory}. Dzięki temu możemy dokonać analizy zarówno zależności wszystkich trzech klas ze sobą, jak i połączenia tylko dwóch klas lub rozłożenia jednej klasy. 
\par
Na rysunkach \ref{krata_2kolory} oraz \ref{krata_3kolory} można dostrzec, że program poradził sobie bardzo dobrze z oddzieleniem klasy irysów Setosa (zielony kolor), wydzielił również klasy irysów Versicolor (czerwony kolor) oraz Virginica (niebieski kolor). Wydzielone klasy rozpoznajemy jako zgrupowania na kracie neuronów (wizualizowanych jako kulki) podobnego koloru. Zmieniając rozmiar kraty, co zostało zaprezentowane na rysunku \ref{krata_rozmiary}, również możemy zauważyć że klasa zielona - irysów Setosa jest bardzo dobrze oddzielona, bez względu na rozmiar kraty. Natomiast widać, że algorytm ma największe problemy z oddzieleniem klasy niebieski - irysów Virginica. W szczególności na kracie $10x10$ oraz $4x4$ można zaobserwować, że element klasy irysów Virginica znajduje się w grupie klasy irysów Versicolor. Aby lepiej to zaobserwować możemy włączyć tylko wizualizację klasy irysów Virginica i wtedy dokładnie widać, że część elementów odłączyła się od grupy. Zachowanie takie może być spowodowane podobieństwem danych klas irysów Versicolor i Virginica. Dokonaliśmy również badania analizy skupień ze względu na ilość iteracji. Wyniki tych analiz zostały przedstawione na rysunku \ref{krata_iteracje}. Można na nim zaobserwować, że im więcej iteracji tym lepiej udało mu sie wyodrębnić poszczególne klasy, w szczególności różnice między klasami irysów Versicolor i Virginica. Klasę irysów Setosa algorytm potrafi dobrze klasyfikować nawet przy niewielkiej ilości iteracji.
     
\subsection{Analiza otrzymanych wyników} 
Przedstawione wyniki wskazują na to, iż algorytm dobrze radzi sobie z obdzielaniem poszczególnych klas irysów. Zarówno na kracie wielkości $10x10$ jak i $3x3$ jesteśmy w stanie wyróżnić poszczególne klasy irysów. Podobnie nawet przy niewielkiej ilość iteracji algorytm jest w stanie wydzielić skupienia. Na wszystkich zaprezentowanych wynikach widać, iż zaimplementowany algorytm samoorganizującej się sieci Kohonena najlepiej poradził sobie z wydzielaniem klasy irysów Setosa (zielony kolor), natomiast spotyka pewne problemy z całkowitym wydzielaniem klasy irysów Virginica(niebieski). Lecz nie są to duże podziały - zazwyczaj tylko niewielka ilość (jeden lub dwa neurony na dużej kracie) odstają od reszty klasy. Oprócz tych elementów reszta neuronów poszczególnych klas irysów jest poprawnie zgrupowana.  
     
\newpage
\section{Konkluzje i plany dalszych badań}
\label{konkluzje}

Przeglądając wyniki działania programu przedstawione w poprzednim rozdziale zauważyć można było, że algorytm dosyć dobrze potrafił zgrupować podany zbiór danych wykorzystując do tego celu prosty algorytm. Zwiększając rozmiar sieci otrzymywaliśmy większą liczbę klas, na które dane wejściowe były dzielone. Zauważyć to można było w sieci wymiarów $10x10$, która oprócz ostrych barw czerwieni, zieleni i błękitu posiadała także wiele barw pośrednich, nie zawsze także będących zgrupowanych obok siebie. Badając zbiór kwiatów irysów wiedzieliśmy, że poszukujemy trzech głównych gatunków kwiatów. Bardzo dobrze grupowania tworzone były na mniejszych sieciach, jednak zawsze tworzony był neuron, który w pełni nie był przypisany do określonej grupy.

\par Omawiana w tej pracy sieć, jak już niejednokrotnie było wspomniane, nadaje się do grupowania danych. Jednak o wiele ciekawsze mogą być wyniki działań na większych zbiorach i sieciach. Tworząc większe sieci warto użyć programowania równoległego. W naszym programie zostało to przykładowo zaimplementowane, jednak ze względu na małe rozmiary sieci może nie dawać szybszych rezultatów obliczeń. Niestety problemem rozdzielenia działań, jest zależność obliczeń nowego kroku od poprzedniego, jednak samo wyszukiwanie i modyfikacja wag sąsiadów można było z łatwością rozdzielić.
\par Rozważając problem na sieciach neuronowych warto zaimplementować algorytm na kartach graficznych. Dzisiejsze karty graficzne wyposażone w wiele procesorów i funkcje matematyczne bardzo dobrze nadają się do implementacji sieci. Być może w przyszłości sztuczny mózg będzie wywodził się z procesorów kart graficznych dodatkowo połączonych ze sobą z ewentualną hybrydą innych rozwiązań, jak automaty komórkowe.
  

\newpage
\section{Bibliografia}

\begin{thebibliography}{9}
  
\bibitem{fisher}
  Fisher, R.A.
  \emph{The Use of Multiple Measurements in Taxonomic Problems}.
  Annals of Eugenics, 1997, 

\bibitem{fri}
  Fritzke, B.
  \emph{Some Competitive Learning Methods}.
  Draft Version, Institute for Neural. Computation, Ruhn-Universitat Bochum, 1997  

\bibitem{kohonen_first}
  Kohonen, T.
  \emph{Analysis of a simple self-organizing process}.
  Biol. Cybern., 44, 1982, pp. 135-140.  

\bibitem{tablice}
  Porikili, F.
  Kocak, T.
  \emph{Robust License Plate Detection Using Covariance Descriptor in a Neural Network Framework}
  Mitsubishi Electric Research
    
\bibitem{rutkowski}
  Rutkowski, L.
  \emph{Metody i techniki sztucznej inteligencji}
  PWN, 2005
  
\bibitem{tadeusiewicz}
  Tadeusiewicz, R.
  \emph{Sieci neuronowe}
  Akademicka Oficyna Wydawnicza, 1993

 
\end{thebibliography}

\end{document}
